﻿#region Using Statements
using Microsoft.Xna.Framework.Storage;
using System;

#endregion

namespace GameBase.Storage
{
    /// <summary>
    /// References a method to be called when performing an storage operation.
    /// </summary>
    /// <param name="container">Storage container on which perform the operation.</param>
    public delegate void StorageCallback(StorageContainer container);

    /// <summary>
    /// Basic functionality needed for data storage.
    /// </summary>
    public class StorageManager
    {
        #region Singleton

        // the only instance of this class... eager initialization
        static readonly StorageManager instance = new StorageManager();

        // private constructor
        private StorageManager() { }

        /// <summary>
        /// Gets a common instance of this class.
        /// </summary>
        public static StorageManager Instance
        {
            get { return instance; }
        }

        #endregion

        #region Storage Management

        // storage device on which perform operations
        StorageDevice device;

        /// <summary>
        /// Retrieves an storage container asynchronously and performs on it an specified operation.
        /// </summary>
        /// <param name="container">Storage container identification.</param>
        /// <param name="callback">An StorageCallback that represents the method called when the storage container has been retrieved.</param>
        public void StorageOperation(string container, StorageCallback callback)
        {
            if (callback == null)
                throw new ArgumentNullException("Value cannot be null.");

            // storage device already retrieved
            if (device != null && device.IsConnected)
            {
                device.BeginOpenContainer(container,
                    (auxResultContainer) =>
                    {
                        using (StorageContainer auxContainer = device.EndOpenContainer(auxResultContainer))
                        {
                            StorageCallback auxCallback = auxResultContainer.AsyncState as StorageCallback;
                            if (auxCallback != null)
                                auxCallback(auxContainer);
                        }
                    }, callback);

                return;
            }

            // storage device must be retrieved
            //if (!Guide.IsVisible)
            device = null;
            StorageDevice.BeginShowSelector(
                (auxResultDevice) =>
                {
                    device = StorageDevice.EndShowSelector(auxResultDevice);
                    if (device != null && device.IsConnected)
                    {
                        device.BeginOpenContainer(container,
                            (auxResultContainer) =>
                            {
                                using (StorageContainer auxContainer = device.EndOpenContainer(auxResultContainer))
                                {
                                    StorageCallback auxCallback = auxResultContainer.AsyncState as StorageCallback;
                                    if (auxCallback != null)
                                        auxCallback(auxContainer);
                                }
                            }, callback);
                    }
                }, null);
        }

        #endregion
    }
}
